package nckd.wnqjt.tmc.tda.plugin.form;

import kd.bos.algo.*;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.report.*;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.util.StringUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Classname BankLoanRepayQueryPlugin
 * @Description 银行借款还款进度表
 * @Version 1.0.0
 * @Date 2024/11/12 上午9:54
 * @Created by xiaoxiaopeng
 */
public class BankLoanRepayQueryPlugin extends AbstractReportListDataPlugin {

    //提款中,已提款,已部分还款
    private final String[] drawTypes = {"drawed", "partpayment"};

    @Override
    public DataSet query(ReportQueryParam reportQueryParam, Object o) throws Throwable {

        //取查询字段
        List<String> filedList = new ArrayList<>();
        List<ReportColumn> fileds = (List<ReportColumn>) reportQueryParam.getCustomParam().get("fileds");
        fileds.forEach(item -> {
            filedList.add(item.getFieldKey());
        });

        //过滤条件
        List<QFilter> filters = new ArrayList<>();
        List<FilterItemInfo> filterItems = reportQueryParam.getFilter().getFilterItems();
        for (FilterItemInfo item : filterItems) {
            if ("nckd_orgf".equals(item.getPropName()) && item.getValue() != null) {
                //DynamicObject org = (DynamicObject) item.getValue();
                //filters.add(new QFilter("org.id", QCP.equals, org.getPkValue()));
                Object value = item.getValue();
                DynamicObjectCollection nckdOrg = null;
                if (value != null) {
                    nckdOrg = (DynamicObjectCollection) value;
                    List<Long> longList = nckdOrg.stream().map(e -> e.getLong("id")).collect(Collectors.toList());
                    QFilter orgFilter = new QFilter("org.id", QCP.in, longList);
                    filters.add(orgFilter);
                }
            }
        }

        //单据状态=已审核
        QFilter statusFilter = new QFilter("billstatus", QCP.equals, "C");
        //确认状态=已确认
        QFilter confirmFilter = new QFilter("confirmstatus", QCP.equals, "yetconfirm");
        //债权人类型=【银行】
        QFilter bankFilter = new QFilter("creditortype", QCP.equals, "bank");
        //提款业务状态=已提款
        QFilter drawFilter = new QFilter("drawtype", QCP.in, drawTypes);

        filters.add(statusFilter);
        filters.add(confirmFilter);
        filters.add(bankFilter);
        filters.add(drawFilter);

        String filed = "id,billstatus,confirmstatus,creditortype,drawtype,org.id,org.name as nckd_org,textcreditor as nckd_bank,drawamount as nckd_repayamount,repayplan_entry.exrepaymentdate,repayplan_entry.enotrepayamount,expiredate";
        DataSet dataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cfm_loanbill", filed, filters.toArray(new QFilter[filters.size()]), null);

        /**
         * 提取数据
         */
        Map<String, List<Map<String, Object>>> billMap = new HashMap<>();
        Iterator<Row> iterator = dataSet.copy().iterator();
        while (iterator.hasNext()) {
            Row row = iterator.next();
            Object id = row.get("id");
            if (!billMap.containsKey(id.toString())) {
                Map<String, Object> map = new HashMap<>();
                List<Map<String, Object>> list = new ArrayList<>();
                map.put("nckd_org", row.get("nckd_org"));
                map.put("nckd_bank", row.get("nckd_bank"));
                map.put("nckd_repayamount", row.get("nckd_repayamount"));
                map.put("exrepaymentdate", row.get("repayplan_entry.exrepaymentdate"));
                map.put("enotrepayamount", row.get("repayplan_entry.enotrepayamount"));
                map.put("expiredate", row.get("expiredate"));
                list.add(map);
                billMap.put(id.toString(), list);
            } else {
                List<Map<String, Object>> oldList = billMap.get(id.toString());
                Map<String, Object> map = new HashMap<>();
                map.put("nckd_org", row.get("nckd_org"));
                map.put("nckd_bank", row.get("nckd_bank"));
                map.put("nckd_repayamount", row.get("nckd_repayamount"));
                map.put("exrepaymentdate", row.get("repayplan_entry.exrepaymentdate"));
                map.put("enotrepayamount", row.get("repayplan_entry.enotrepayamount"));
                map.put("expiredate", row.get("expiredate"));
                oldList.add(map);
            }
        }

        List<DataType> dataTypes = new ArrayList<>();
        for (int i = 0; i < filedList.size(); i++) {
            if (i <= 2) {
                dataTypes.add(DataType.StringType);
            } else {
                dataTypes.add(DataType.BigDecimalType);
            }
        }

        //构建空的dataSet
        RowMeta createRowMeta = RowMetaFactory.createRowMeta(filedList.toArray(filedList.toArray(new String[filedList.size()])), dataTypes.toArray(dataTypes.toArray(new DataType[dataTypes.size()])));
        DataSetBuilder dataSetBuilder = Algo.create(this.getClass().getName()).createDataSetBuilder(createRowMeta);

        SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
        SimpleDateFormat monthFormat = new SimpleDateFormat("yyyyMM");
        String nowYear = yearFormat.format(new Date());

        for (Map.Entry<String, List<Map<String, Object>>> entry : billMap.entrySet()) {
            List<Map<String, Object>> rows = entry.getValue();
            Object[] row = new Object[filedList.size()];
            String[] yearFiled = {"", "", ""};//本年字段标识
            BigDecimal[] yearAmount = {BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO};
            rows.forEach(t -> {
                Date date = (Date) t.get("exrepaymentdate");
                String year = yearFormat.format(date);//日期年
                String month = monthFormat.format(date);//日期年月
                Arrays.asList(createRowMeta.getFieldNames()).forEach(f -> {
                    if (("year" + nowYear).equals(f)) {
                        yearFiled[0] = f;
                    }
                    if (("year" + ((Integer.parseInt(nowYear)) + 1)).equals(f)) {
                        yearFiled[1] = f;
                    }
                    if (("year" + ((Integer.parseInt(nowYear)) + 2)).equals(f)) {
                        yearFiled[2] = f;
                    }
                    BigDecimal enotrepayamount = (BigDecimal) t.get("enotrepayamount");
                    if (("month" + month).equals(f)) {
                        if (f.contains(nowYear)) {
                            yearAmount[0] = yearAmount[0].add(enotrepayamount);
                        }
                        String year1 = String.valueOf((Integer.parseInt(nowYear) + 1));
                        if (f.contains(year1)) {
                            yearAmount[1] = yearAmount[1].add(enotrepayamount);
                        }
                        row[Arrays.asList(createRowMeta.getFieldNames()).indexOf(f)] = enotrepayamount.divide(new BigDecimal(10000));
                    }
                    if (StringUtils.isNotEmpty(yearFiled[2]) && yearFiled[2].contains(year)) {
                        yearAmount[2] = yearAmount[2].add(enotrepayamount);
                    }
                });
            });
            row[0] = rows.get(0).get("nckd_org");//单元
            row[1] = rows.get(0).get("nckd_bank");//金融机构
            Date expiredate = (Date) rows.get(0).get("expiredate");
            if (expiredate != null && expiredate.getTime()<new Date().getTime()) {
                row[2] = "2";
            }else {
                row[2] = "1";
            }
            BigDecimal amount = (BigDecimal) rows.get(0).get("nckd_repayamount");
            row[3] = (amount.divide(new BigDecimal(10000)));//金额
            if (StringUtils.isNotEmpty(yearFiled[0])) {
                row[Arrays.asList(createRowMeta.getFieldNames()).indexOf(yearFiled[0])] = yearAmount[0].divide(new BigDecimal(10000));
            }
            if (StringUtils.isNotEmpty(yearFiled[1])) {
                row[Arrays.asList(createRowMeta.getFieldNames()).indexOf(yearFiled[1])] = yearAmount[1].divide(new BigDecimal(10000));
            }
            if (StringUtils.isNotEmpty(yearFiled[2])) {
                row[Arrays.asList(createRowMeta.getFieldNames()).indexOf(yearFiled[2])] = yearAmount[2].divide(new BigDecimal(10000));
            }
            dataSetBuilder.append(row);
        }
        //根据公司排序
        DataSet bnakLoanDataSet = dataSetBuilder.build().orderBy(new String[]{"nckd_org"});
        bnakLoanDataSet = bnakLoanDataSet.addField("1", "count");
        //合计字段
        GroupbyDataSet sumGroup = bnakLoanDataSet.copy().groupBy(new String[]{"nckd_org"});
        //公司合计行标识
        String sumFiled = "nckd_org,concat('合计') as nckd_bank,'1' as nckd_hig";
        for (int i = 3; i < filedList.size(); i++) {
            sumFiled = sumFiled + "," + filedList.get(i);
            sumGroup = sumGroup.sum(filedList.get(i));
        }
        DataSet orgCountDataSet = sumGroup.finish();
        //新增公司合计行
        orgCountDataSet = orgCountDataSet.select(sumFiled).addField("2", "count");
        /**
         *  增加总计行
         */
        GroupbyDataSet totalGroup = orgCountDataSet.copy().groupBy(new String[]{"nckd_bank"});
        //总计行标识
        String totalFiled = "concat('总计') as nckd_org,'-' as nckd_bank,'1' as nckd_hig";
        for (int i = 3; i < filedList.size(); i++) {
            totalFiled = totalFiled + "," + filedList.get(i);
            totalGroup = totalGroup.sum(filedList.get(i));
        }
        DataSet totalDataSet = totalGroup.finish();
        totalDataSet = totalDataSet.select(totalFiled).addField("3", "count").addField("2", "totalCount");

        DataSet resultDataSet = bnakLoanDataSet.union(orgCountDataSet);
        resultDataSet = resultDataSet.addField("1", "totalCount");
        resultDataSet = resultDataSet.union(totalDataSet).orderBy(new String[]{"nckd_org", "count"}).orderBy(new String[]{"totalCount"});

        return resultDataSet;
    }
}
